RecyclerView是一個很方便拿來顯示大量數據的工具,比方說我可能有30筆或更多的資料要顯示,這個時候用TextView可能會出現資料超出視窗的問題,這個時候就是使用RecyclerView最好時機,他可以達到類似滾動條的功能,建立一個讓你可以上下滑動介面,解決了畫面不夠顯示的問題,雖然剛開始可能會覺得很麻煩不好記,但熟練後絕對是一個十分好用的工具!
下面就依序地來講解:
這邊我一樣先貼上本此的Github
首先在要使用RecyclerView的布局檔將RecyclerView放到要顯示的地方,就像下面展示的一樣
(記得綁定邊框)
再來要將這個RecyclerView命名,點選spilt
找到你的RecyclerView,幫他加上idandroid:id="@+id/recyclerview"
,當然不是一定要叫作recyclerview這部分就自由命名 只要不要名字怪到讓自己記不住就好
到這裡第一步就完成囉~
這裡要先新建一個新的布局,找到你的layout
點右鍵,再選取Layout Resource File
,像下面這樣
之後在File Name
打上名稱按下OK就成功創建一個布局檔了,本次實作我新增了一個recycleritem
詳細的程式碼可以翻這次的Github,簡單來說這個地方要做RecyclerView要展示的畫面,以這次的實作來說我拉了六個TextView,三個用來分類三個用來填入不同的資料,再後面的程式碼要做的就是綁定Item的布局檔,然後控制這裡拉的物件。
下面我會介紹跟之前的布局比較不一樣的地方
這個部分我將原本預設的androidx.constraintlayout.widget.ConstraintLayout
換成了LinearLayout
,兩個最大的差別是,前者要拉物件的大小、綁定框架,這些都需要用滑鼠慢慢地拉,後者可以使用權重
調整物件的大小和位置,而且因為後者不用綁定框架,所以在跑版的問題上也是有一定程度上的解決,是一個很方便使用的工具。LinearLayout
本身有分平行(horizontal)
跟垂直(vertical)
,前者會規定在裡面的物件只能橫向排列
,後者會規定物件只能垂直排列
,可以使用orientation
來調整LinearLayout,接著要說到layout_weight
,這個就是在設定「權重
」,實際效果可以看下面:
LinearLayout
是「垂直」的話,在裡面的物件height
就要設為0dp
靠權重去設定大小就好,反之是「平行」的就將width
設為0dp
。首先要先建立一個新的class
,找到java底下的第一個資料夾,按右鍵點選New
,再選取Java Class
大概像下面這樣
再來會跳出這個畫面
接著要在Name
那一欄填入class的名稱,這邊我是填入MyListAdapter
,按下Enter
就可以創立一個class了。
接著我們要繼承(extends)
RecyclerView的Adapter,因此我們要在class的名稱後面輸入extends RecyclerView.Adapter<你的class名稱.ViewHolder>
,就像這樣
public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ViewHolder>
再來會看到底下會多了一條紅線,這是因為RecyclerView的Adapter有三個分法要寫,這邊他是在提醒你有方法還未引入,可以直接用ALT+ENTER
來幫你引入方法,引入後會看到下面多了這三個方法
@NonNull
@Override
public MyListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull MyListAdapter.ViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return 0;
}
MyListAdapter.ViewHolder onCreateViewHolder
這裡在綁定布局檔通常綁定的會是recycleritem
,然後再return
這個view,寫法會像下面這樣 @NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//這裡綁定RecyclerView的Item布局
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleritem,parent,false);
return new ViewHolder(view);
}
可以看到我將View綁定到了recycleritem上,再將這個view給return。
onBindViewHolder
,這裡是在控制物件的動作,以這次的實作來說我要控制的就是TextViewgetItemCount()
。這裡要你傳入你的RecyclerView的長度
,通常就是傳入資料的長度,比如我的資料是用一個arraylist
存取的話,那這個資料的長度就可以用size()
方法來抓長度。再來你可能會注意到ViewHolder
會是紅字,這是因為我們在繼承的時候自定義了自己的ViewHolder,所以出現紅字就是要你定義一個ViewHolder,一樣可以用ALT+ENTER
來幫忙引入ViewHolder,最後就會長下面這樣
public class ViewHolder extends RecyclerView.ViewHolder {
//這裡宣告物件變數
public ViewHolder(@NonNull View itemView) {
super(itemView);
//這裡綁定物件id
}
}
這裡是用來宣告物件和綁定物件id,綁定物件id跟之前的會長的不太一樣,像是原本要綁定一個TextView的id要這樣打
textView = findByItemId(R.id.textview);
但這裡要改成
textView = itemView.findByItemId(R.id.textview);
最後要提到本次實作最重要的地方「建構元
」,我們要在ListAdapter寫建構元,之後在MainActivity時才可以向ListAdapter傳入資料,讓ListAdapter可以使用這些資料,算是製作一個將ListAdapter與MainActivity連結的橋樑,下面就開始講解:
要往建構元傳入的資料要是什麼樣的型態依照當下的設計決定,以我來說我最常使用的是將HashMap
結合到ArrayList
裡面,HashMap相當於字典
,需要給予HashMapKey
和Value
,之後我只要再將填好資料的HashMap加入到ArrayList,之後我要調用資料時,就可以用Key
跟索引值
去抓我要的資料;另外一個我比較常用的是String的List,通常會用在資料只有單一一種的時候。
要先建立一個可以接收傳入資料的ArrayList,之後就可以建立這個class的建構元
整體會長下面這樣
private ArrayList<HashMap<String,String>> mArrayList;
public MyListAdapter(ArrayList<HashMap<String,String>> arrayList){
//這裡創建了一個建構元,接收從外面丟進來的陣列
this.mArrayList = arrayList;
//可以用this.來代表這裡建立的變數
}
可以看到我的ArrayList裡面放入了HashMap,然後規定HashMap的Key跟Value是String型態。
這裡要宣告RecyclerView跟MyListAdapter
private MyListAdapter myListAdapter;
private RecyclerView recyclerView;
接下來就是使用RecyclerView的重點
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));//綁定RecyclerView
myListAdapter = new MyListAdapter(arrayList);//將我的ArrayList丟入ListAdapter
recyclerView.setAdapter(myListAdapter);
第一行是在綁定RecyclerView的id,第二行在綁定RecyclerView,第三行將我的資料丟入建構元,第四行將我的ListAdapter設定給RecyclerView的Adapter。
再來是製作假資料的方法
private void makeData() {//建立假資料
for (int i = 0; i < 26; i++) {
HashMap hashMap = new HashMap();
hashMap.put("students",students_data[i]);
arrayList.add(hashMap);//用add的方式把HashMap加入到ArrayList裡
}
}
這邊我是將假資料用一個方法打包,可以看到新增資料的方法是將資料丟給HashMap再加進arrayList,當for迴圈跑完我的假資料就建立完成了,之後就是將這個資料丟給MyListAdapter就完成一切的設定了。